package com.moefor.clover.controller;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.google.code.kaptcha.Constants;
import com.moefor.clover.model.Market;
import com.moefor.clover.model.User;
import com.moefor.clover.model.element.Picture;
import com.moefor.clover.model.enums.CloverSessionKey;
import com.moefor.clover.service.SecurityUserService;
import com.moefor.clover.service.UserService;
import com.moefor.clover.util.Encrypt;
import com.moefor.clover.util.MessagePackager;


@Controller
public class UserController {
	@Resource
	private UserService userService;
	
	@Resource
	private SecurityUserService securityUserService;
	
	@Resource
	private AuthenticationManager authenticationManager;
	
	@ResponseBody
	@RequestMapping(value = "/common/signin.do", method = RequestMethod.POST)
	public MessagePackager login(HttpSession session,
			@RequestParam("username") String username,
			@RequestParam("password") String password,
			@RequestParam("captcha") String captcha){
		MessagePackager msgPack;
		if(captcha == null ||
			!captcha.equals(session.getAttribute(Constants.KAPTCHA_SESSION_KEY))){
			msgPack = new MessagePackager(false, "CAPTCHA_ERROR", "验证码错误!");
			return msgPack;
		}
		if(username == null ||
			password == null ||
			username.length() < 6 ||
			password.length() < 6){
			msgPack = new MessagePackager(false, "DATA_FORMAT_ERROR", "用户名或密码格式错误!");
			return msgPack;
		}
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
		try {
			Authentication authentication = authenticationManager.authenticate(authRequest);
			SecurityContextHolder.getContext().setAuthentication(authentication);
			session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
			msgPack = userService.val(username, password);
			if(!msgPack.getState()){
				session.removeAttribute("SPRING_SECURITY_CONTEXT");
				throw new Exception();
			}
			User user = (User)msgPack.getData();
			session.setAttribute(CloverSessionKey.USER, user);
			session.setAttribute(CloverSessionKey.USER_PASSWORD, password);
		} catch (AuthenticationException ex) {
			msgPack = new MessagePackager(false, null, "账号或密码错误!");
		} catch (Exception e) {
			// TODO: handle exception
			msgPack = new MessagePackager(false, null, "未知错误!");
		}
		return msgPack;
	}
	
	@ResponseBody
	@RequestMapping("/user/signout.do")
	public MessagePackager logout(HttpSession session){
		MessagePackager msgPack = new MessagePackager();
		User user = (User)session.getAttribute(CloverSessionKey.USER);
		if(user == null || session.getAttribute("SPRING_SECURITY_CONTEXT") == null){
			msgPack.setState(false);
			msgPack.setCode("USER_UN_LOGIN");
			msgPack.setData("用户未登录!");
		}else{
			msgPack.setState(true);
			msgPack.setData("注销成功!");
		}
		session.invalidate();
		SecurityContextHolder.clearContext();
		return msgPack;
	}
	
	@ResponseBody
	@RequestMapping(value = "/user/update.do", method = RequestMethod.POST)
	public MessagePackager update(HttpSession session,
			@RequestParam("password") String password,
			@RequestParam("phonenum") String tel,
			@RequestParam("email") String email){
		MessagePackager msgPack = new MessagePackager();
		User user = (User)session.getAttribute(CloverSessionKey.USER);
		if(user == null || session.getAttribute("SPRING_SECURITY_CONTEXT") == null){
			msgPack.setState(false);
			msgPack.setCode("USER_UN_LOGIN");
			msgPack.setData("用户未登录!");
			return msgPack;
		}
		Pattern regxEmail = Pattern.compile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?");
		if(!regxEmail.matcher(email).matches()){
			msgPack = new MessagePackager(false, "ERROR", "电子邮箱格式错误!");
			return msgPack;
		}
		Pattern regxTel = Pattern.compile("^[1][3,5,7,8][0-9]{9}$");
		if(!regxTel.matcher(tel).matches()){
			msgPack = new MessagePackager(false, "ERROR", "手机号码格式错误!");
			return msgPack;
		}
		if(password.length() < 6){
			msgPack = new MessagePackager(false, "ERROR", "密码格式错误!");
			return msgPack;
		}
		String passwordOri = (String)session.getAttribute(CloverSessionKey.USER_PASSWORD);
		if(Encrypt.MD5(passwordOri).equals(password)) password = passwordOri;
		msgPack = userService.update(user.getId(), password, email, tel, user.getAvator().getUrl());
		if(msgPack.getState()){
			session.setAttribute(CloverSessionKey.USER, userService.get(user.getId()).getData());
		}
		return msgPack;
	}
	
	@ResponseBody
	@RequestMapping(value = "/user/update_avator.do")
	public MessagePackager addGoods(
			HttpSession session,
			@RequestParam(value = "file") MultipartFile file){
		MessagePackager msgPack = new MessagePackager(false, null, "未知错误!");
		User user = (User)session.getAttribute(CloverSessionKey.USER);
		if(user == null || session.getAttribute("SPRING_SECURITY_CONTEXT") == null){
			msgPack.setState(false);
			msgPack.setCode("USER_UN_LOGIN");
			msgPack.setData("用户未登录!");
			return msgPack;
		}
		if(file.isEmpty()){
			msgPack.setData("上传文件失败,文件为空!");
			return msgPack;
		}
		String url = "data/img/" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + 
				(int) ((new Random().nextDouble() * (99999 - 10000 + 1)) + 10000) + 
				Encrypt.MD5(file.getOriginalFilename()) + ".jpg";
		String filePath = session.getServletContext().getRealPath("/") + url; 
		try {
			file.transferTo(new File(filePath));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			msgPack.setData("上传文件失败!");
			e.printStackTrace();
			return msgPack;
		}
		String passwordOri = (String)session.getAttribute(CloverSessionKey.USER_PASSWORD);
		msgPack = userService.update(user.getId(), passwordOri, user.getEmail(), user.getTel(), url);
		if(msgPack.getState()){
			session.setAttribute(CloverSessionKey.USER, userService.get(user.getId()).getData());
		}
		return msgPack;
	}
	
	@ResponseBody
	@RequestMapping(value = "/common/signup.do", method = RequestMethod.POST)
	public MessagePackager regist(HttpSession session,
			@RequestParam("captcha") String captcha,
			@RequestParam("username") String username,
			@RequestParam("password") String password,
			@RequestParam("phonenum") String tel,
			@RequestParam("email") String email
			){
		MessagePackager msgPack;
		if(captcha == null ||
			!captcha.equals(session.getAttribute(Constants.KAPTCHA_SESSION_KEY))
			){
			msgPack = new MessagePackager(false, "CAPTCHA_ERROR", "验证码错误!");
			return msgPack;
		}
		Pattern regxEmail = Pattern.compile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?");
		if(!regxEmail.matcher(email).matches()){
			msgPack = new MessagePackager(false, "ERROR", "电子邮箱格式错误!");
			return msgPack;
		}
		Pattern regxTel = Pattern.compile("^[1][3,5,7,8][0-9]{9}$");
		if(!regxTel.matcher(tel).matches()){
			msgPack = new MessagePackager(false, "ERROR", "手机号码格式错误!");
			return msgPack;
		}
		if(username.length() < 6 || password.length() < 6){
			msgPack = new MessagePackager(false, "ERROR", "用户名或密码格式错误!");
			return msgPack;
		}
		msgPack = userService.regist(username, password, email, tel);
		if(msgPack.getState()){
			UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
			Authentication authentication = authenticationManager.authenticate(authRequest);
			SecurityContextHolder.getContext().setAuthentication(authentication);
			session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
			session.setAttribute(CloverSessionKey.USER, msgPack.getData());
		}
		return msgPack;
	}
}
